home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
05
/
struc_pr.asc
< prev
next >
Wrap
Text File
|
1991-03-15
|
6KB
|
177 lines
_STRUCTURED PROGRAMMING COLUMN_
by Jeff Duntemann
[LISTING ONE]
CONST
COMPORT = 2; { 1 = COM1: 2 = COM2: }
COMBASE = $2F8;
PORTBASE = COMBASE OR (COMPORT SHL 8); { $3F8 for COM1: $2F8 for COM2: }
{ 8250 control registers, masks, etc. }
RBR = PORTBASE; { 8250 Receive Buffer Register }
THR = PORTBASE; { 8250 Transmit Holding Register }
IER = PORTBASE + 1; { 8250 Interrupt Enable Register }
LCR = PORTBASE + 3; { 8250 Line Control Register }
MCR = PORTBASE + 4; { 8250 Modem Control Register }
LSR = PORTBASE + 5; { 8250 Line Status Register }
DLL = PORTBASE; { 8250 Divisor Latch LSB when DLAB=1 }
DLM = PORTBASE + 1; { 8250 Divisor Latch MSB when DLAB=1 }
DLAB = $80; { Value for Divisor Latch Access Bit }
THRE = $20; { Value for Transmit Holding Register Empty bit }
BAUD300 = 384; { Value for 300 baud operation }
BAUD1200 = 96; { Value for 1200 baud operation }
DTR = $01; { Value for Data Terminal Ready }
RTS = $02; { Value for Ready To Send }
NOPARITY = 0; { Comm format value for no parity }
BITS8 = $03; { Comm format value for 8 bits }
[LISTING TWO]
{--------------------------------------------------------------}
{ POLLTERM }
{ by Jeff Duntemann }
{ Turbo Pascal V6.0 }
{ Last update 2/3/91 }
{ This is a *truly* dumb terminal program that operates by }
{ polling the serial port's registers and does NOT use }
{ interrupts. It's a good illustration of why interrupts are }
{ necessary... }
{ PollTerm can be set to use either COM1: or COM2: by setting }
{ the COMPORT constant to 1 (for COM1) or 2 (for COM2:) as }
{ as appropriate and recompiling. }
{--------------------------------------------------------------}
PROGRAM PollTerm;
USES DOS,CRT;
{$I REGISTERS.DEF }
VAR
Quit : Boolean; { Flag for exiting the program }
HiBaud : Boolean; { True if 1200 baud is being used }
KeyChar : Char; { Character from keyboard }
CommChar : Char; { Character from the comm port }
Divisor : Word; { Divisor value for setting baud rate }
Clearit : Byte; { Dummy variable }
NoShow : SET OF Char; { Don't show characters set }
PROCEDURE SetRate(Divisor : Word);
BEGIN
{ Set the DLAB flag to 1: }
Port[LCR] := Port[LCR] OR DLAB;
{ Load the divisor latches: }
Port[DLL] := Lo(Divisor);
Port[DLM] := Hi(Divisor);
{ Clear the DLAB flag to 0:}
Port[LCR] := Port[LCR] AND (NOT DLAB);
END;
FUNCTION InStat : Boolean;
BEGIN
{ Bit 0 of LSR goes high when a char is waiting: }
InStat := Boolean(Port[LSR] AND $01);
END;
FUNCTION OutStat : Boolean;
BEGIN
{ Bit 5 of LSR goes high when the THR is ready for another char: }
OutStat := ((LSR AND THRE) = THRE);
END;
FUNCTION InChar : Char;
BEGIN
InChar := Char(Port[RBR]);
END;
PROCEDURE OutChar(Ch : Char); { Send a character to the comm port }
BEGIN
Port[THR] := Byte(Ch) { Put character ito Transmit Holding Register }
END;
PROCEDURE UhUh;
VAR
I : Integer;
BEGIN
FOR I := 1 TO 2 DO
BEGIN
Sound(50);
Delay(50);
NoSound;
Delay(50);
END;
END;
{>>>>>POLLTERM MAIN PROGRAM<<<<<}
BEGIN
HiBaud := True; { PollTerm defaults to 1200 baud; if "300"}
Divisor := BAUD1200; { is entered after "POLLTERM" on the }
IF ParamCount > 0 THEN { command line, then 300 baud is used }
IF ParamStr(1) = '300' THEN
BEGIN
HiBaud := False;
Divisor := BAUD300
END;
SetRate(Divisor); { Set the baud rate }
Port[IER] := 0; { Disable 8259 interrupts }
Port[LCR] := BITS8 OR NOPARITY; { Set word length and parity }
Port[MCR] := DTR OR RTS; { Enable DTR, & RTS }
Clearit := Port[RBR]; { Clear any garbage from RBR }
Clearit := Port[LSR]; { Clear any garbage from LSR }
DirectVideo := True;
NoShow := [#0,#127]; { Don't display NUL or RUBOUT }
ClrScr;
Writeln('>>>POLLTERM by Jeff Duntemann');
Quit := False; { Exit POLLTERM when Quit goes to True }
REPEAT
IF InStat THEN { If a character comes in from the modem }
BEGIN
CommChar := InChar; { Go get character }
CommChar := Char(Byte(CommChar) AND $7F); { Mask off high bit }
IF NOT (CommChar IN NoShow) THEN { If we can show it,}
Write(CommChar) { then show it! }
END;
IF KeyPressed THEN { If a character is typed at the keyboard }
BEGIN
KeyChar := ReadKey; { First, read the keystroke }
IF KeyChar = Chr(0) THEN { We have an extended scan code here }
UhUh { but we're not using it! }
ELSE
CASE Ord(KeyChar) OF
24 : Quit := True; { Ctrl-X: Exit PollTerm }
26 : ClrScr; { Ctrl-Z: Clear the screen }
ELSE BEGIN
WHILE NOT OutStat DO BEGIN END; { I.e., nothing }
OutChar(KeyChar)
END;
END; { CASE }
END
UNTIL Quit
END.